package academic.ui.client.presenter;


import java.util.ArrayList;
import java.util.Map;

import academic.ui.client.CheckoutServiceAsync;
import ecommerce.soco.shared.GWT_CreditCard;
import ecommerce.soco.shared.GWT_Zone;


import com.allen_sauer.gwt.log.client.Log;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.inject.Inject;
import com.gwtplatform.mvp.client.EventBus;
import com.gwtplatform.mvp.client.PresenterWidget;
import com.gwtplatform.mvp.client.View;

public class CardPresenter extends PresenterWidget<CardPresenter.MyView>
{

	private final CheckoutServiceAsync service;

	
	@Inject 
	public CardPresenter(EventBus eventBus, MyView view,CheckoutServiceAsync service) {
		super(eventBus, view);
		this.service = service;
	}

	
	public interface MyView extends View {

		void setup(GWT_CreditCard[] paymentDetails);

		ArrayList<HasClickHandlers> editCardHandlers();

		void updateEditMode(String id);

		HasClickHandlers saveCard();

		boolean editCardErrors();

		void addZoneOptions(GWT_Zone[] result);

		GWT_CreditCard getCard(String id);

		void closeEditDialog(String id);

		HasClickHandlers addCard();

		void showAddCardDialog();

		HasClickHandlers insertCard();

		boolean inserCardErrors();

		GWT_CreditCard getAddCard();

		void showError(String string);

		void setAsDefault(Integer cardID);
		
		void showDefaultCard();

		void setContext(String string);

		ArrayList<HasClickHandlers> removeCardHandlers();

		Map<String, RadioButton> radios();

	}
	
	@Override
	public void onReveal() {
		super.onReveal();
		Log.debug("CardPresenter onReveal");
		service.getUserPaymentOptions(new AsyncCallback<GWT_CreditCard[]>() {

			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onSuccess(GWT_CreditCard[] result) {
				setupWithHandlers(result);
			}
		});
		
	}
	
	private void setupWithHandlers(GWT_CreditCard[] result) {
		if(result!=null)
		{
			getView().setup(result);
			for(HasClickHandlers editCardHandler : getView().editCardHandlers())
			{
				editCardHandler.addClickHandler(new ClickHandler() {
					@Override
					public void onClick(ClickEvent event) {
						getView().updateEditMode(event.getRelativeElement().getId());
					}
				});
			}
			
			for(HasClickHandlers removeCardHandler : getView().removeCardHandlers())
			{
				removeCardHandler.addClickHandler(new ClickHandler() {
					@Override
					public void onClick(ClickEvent event) {
						if(Window.confirm("Are you sure you want to remove this credit card?"))
						service.removeCard(event.getRelativeElement().getId(),new AsyncCallback<GWT_CreditCard[]>() {

							@Override
							public void onFailure(Throwable caught) {
								// TODO Auto-generated method stub
								
							}

							@Override
							public void onSuccess(GWT_CreditCard[] cards) {
								//recursively call the setup method again with one fewer card
								if(cards!=null)
									setupWithHandlers(cards);
							}
							
						});
					}
				});
			}
			
			for(RadioButton rb : getView().radios().values())
			{
				rb.addClickHandler(new ClickHandler() {

					@Override
					public void onClick(final ClickEvent event) {
						final String elementID=event.getRelativeElement().getId();
						service.setAsDefaultCard(elementID, new AsyncCallback<Boolean>() {

							@Override
							public void onFailure(Throwable caught) {
								// TODO Auto-generated method stub
								
							}

							@Override
							public void onSuccess(Boolean result) {
								//getView().updateDefault(elementID);
							}
							
						});
					}
					
				});
			}
			
			
		}
	}

	@Override
	public void onBind() {
		super.onBind();
		Log.debug("CardPresenter onBind");
		registerHandler(getView().saveCard().addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				if(!getView().editCardErrors())
					Log.debug("edit Card errors");
				else
					service.updateCard(getView().getCard(event.getRelativeElement().getId()), new AsyncCallback<Integer>() {
	
						@Override
						public void onFailure(Throwable caught) {
							// TODO Auto-generated method stub
							
						}
	
						@Override
						public void onSuccess(Integer cardID) {
							getView().setAsDefault(cardID);
							getView().closeEditDialog(String.valueOf(cardID));
							getView().showDefaultCard();
						}
						
					});
			}
			
		}));
		
		registerHandler(getView().addCard().addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				getView().showAddCardDialog();
			}
			
		}));
		
		registerHandler(getView().insertCard().addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				if(getView().inserCardErrors())
					Log.debug("invalid card data");
				else
					service.addCard(getView().getAddCard(), new AsyncCallback<GWT_CreditCard[]>() {

						@Override
						public void onFailure(Throwable caught) {
							// TODO Auto-generated method stub
							
						}

						@Override
						public void onSuccess(GWT_CreditCard[] result) {
							if(result==null)
							{//trying to add card that already exists throw error
								getView().showError("The card you are attempting to add already exists.  To make changes to an existing card click the modify link next to the card.");
							}
							else
							{
								setupWithHandlers(result);
							}
						}
						
					});
			}
			
		}));
		
		service.getZones(new AsyncCallback<GWT_Zone[]>() {

			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onSuccess(GWT_Zone[] result) {
				getView().addZoneOptions(result);
			}
			
		});
	}
	
	@Override
	public void onUnbind() {
		super.onUnbind();
		
	}
	
	@Override
	public void onReset() {
		super.onReset();
		Log.debug("CardPresenter onReset");
	}
	
	

}
